/*

Miranda IM: the free IM client for Microsoft* Windows*

Copyright 2000-2007 Miranda ICQ/IM project, 
all portions of this codebase are copyrighted to the people 
listed in contributors.txt.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
#include "commonheaders.h"
#include "m_icq.h"

namespace NServices {
namespace NSendSMS {

enum EPhoneType {
	PHONE_NONE,
	PHONE_NORMAL,
	PHONE_SMS
};

static HANDLE nhMenuItem	 = NULL;
static HANDLE nhExtraIcon[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE };

/**
 * name:	DBGetPhone
 * desc:	returns the email address of the contact
 * params:	hContact	- handle to contact to read email from
 *			dbv			- retrieves the email address string
 * return:	0 if email was found, 1 otherwise
 **/
static INT DBGetPhone(HANDLE hContact, DBVARIANT *pdbv)
{
	// ignore owner
	if(hContact != NULL) {
		LPCSTR szProto = DBGetContactBaseProto(hContact);
		if(szProto != NULL && (INT)szProto != CALLSERVICE_NOTFOUND && *szProto != 0) {

			// contact has cellular and can receive sms
			if(
				!DBGetSettingEx(hContact, USERINFO, szProto, SET_CONTACT_CELLULAR, pdbv) ||
				!DBGetSettingEx(hContact, USERINFO, szProto, SET_CONTACT_COMPANY_CELLULAR, pdbv)
			  )
			{
				return PHONE_SMS;
			}

			if(
				!DBGetSettingEx(hContact, USERINFO, szProto, SET_CONTACT_PHONE, pdbv) ||
				!DBGetSettingEx(hContact, USERINFO, szProto, SET_CONTACT_COMPANY_PHONE, pdbv)
			  )
			{
				return PHONE_NORMAL;
			}

			// check for private phone numbers
			if(
				!DBGetSetting(hContact, USERINFO, "MyPhone0", pdbv) ||
				!DBGetSetting(hContact, USERINFO, "MyCompanyPhone0", pdbv)
			  )
			{
				if(pdbv->pszVal) {
					if(!strstr(pdbv->pszVal, " SMS"))
						return PHONE_SMS;
					return PHONE_NORMAL;
				}
			}
		}
	}
	return PHONE_NONE;
}

/***********************************************************************************************************
 * Event Handler functions
 ***********************************************************************************************************/

static INT OnCListRebuildIcons(WPARAM wParam, LPARAM lParam)
{
	nhExtraIcon[0] = (HANDLE)CallService(MS_CLIST_EXTRA_ADD_ICON, (WPARAM)NIcoLib::GetIcon(ICO_BTN_PHONE), 0);
	nhExtraIcon[1] = (HANDLE)CallService(MS_CLIST_EXTRA_ADD_ICON, (WPARAM)NIcoLib::GetIcon(ICO_BTN_CELLULAR), 0);
	return 0;
}

/**
 * name:	OnCListApplyIcons
 * desc:	notification handler for clist extra icons to be applied for a contact
 * param:	wParam	- handle to the contact whose extra icon is to apply
 *			lParam	- not used
 **/
static INT OnCListApplyIcons(WPARAM wParam, LPARAM lParam)
{
	DBVARIANT dbv;
	IconExtraColumn iec;

	iec.cbSize = sizeof(IconExtraColumn);
	// to support the ugly shitfuckin' clist_nicer++
	iec.ColumnType = myGlobals.IsCListNicer ? 2 : EXTRA_ICON_SMS;
	switch(DBGetPhone((HANDLE)wParam, &dbv)) {
		case PHONE_NORMAL:
			iec.hImage = nhExtraIcon[0];
			DBFreeVariant(&dbv);
			break;
		case PHONE_SMS:
			iec.hImage = nhExtraIcon[1];
			DBFreeVariant(&dbv);
			break;
		default:
			iec.hImage = INVALID_HANDLE_VALUE;
	}
	CallService(MS_CLIST_EXTRA_SET_ICON, wParam, (LPARAM)&iec);
	return 0;
}

/**
 * name:	OnContactSettingChanged
 * desc:	Notification handler for changed contact settings
 * param:	wParam	-	(HANDLE)hContact
 *			lParam	-	(DBCONTACTWRITESETTING*)pdbcws
 * return:	0 if setting was handled or 1 if not
 **/
static INT OnContactSettingChanged(WPARAM wParam, LPARAM lParam)
{
	DBCONTACTWRITESETTING* pdbcws = (DBCONTACTWRITESETTING*)lParam;
	
	if(
		!mir_stricmp(pdbcws->szSetting, SET_CONTACT_PHONE) ||
		!mir_stricmp(pdbcws->szSetting, SET_CONTACT_CELLULAR) ||
		!_strnicmp(pdbcws->szSetting, "MyPhone0", 8)
	  )
	{
		OnCListApplyIcons(wParam, 0);
	}
	return 0;
}

/***********************************************************************************************************
 * public Module Interface functions
 ***********************************************************************************************************/

/**
 * name:	ApplyCListIcons
 * desc:	force all icons to be reloaded
 * param:	wParam	- handle to the contact whose extra icon is to apply
 *			lParam	- not used
 **/
VOID ApplyCListIcons()
{
	WPARAM wContact;

	//walk through all the contacts stored in the DB
	for(wContact = CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
		wContact != NULL;
		wContact = CallService(MS_DB_CONTACT_FINDNEXT, wContact, 0))
	{
		OnCListApplyIcons(wContact, 0);
	}
}

/**
 * name:	EnableExtraIcons
 * desc:	reload the module
 * params:	bEnable	- determines whether icons are enabled or not
 * return:	0
 **/
VOID EnableExtraIcons(BOOLEAN bEnable, BOOLEAN bUpdateDB) 
{
	static HANDLE	hChangedHook = 0,
					hApplyIconHook = 0,
					hRebuildIconsHook = 0;

	if(!myGlobals.HaveCListExtraIcons)
		return;

	if(bUpdateDB)
		DBWriteContactSettingByte(NULL, MODNAME, SET_CLIST_EXTRAICON_PHONE, bEnable);

	if(bEnable) {
		// hook events
		if(hChangedHook == NULL) hChangedHook = HookEvent(ME_DB_CONTACT_SETTINGCHANGED, OnContactSettingChanged);
		if(hApplyIconHook == NULL) hApplyIconHook = HookEvent(ME_CLIST_EXTRA_IMAGE_APPLY, OnCListApplyIcons);
		if(hRebuildIconsHook == NULL) hRebuildIconsHook = HookEvent(ME_CLIST_EXTRA_LIST_REBUILD, OnCListRebuildIcons);

		OnCListRebuildIcons(0, 0);
	}
	else {
		UnhookEvent(hChangedHook); hChangedHook = NULL;
		UnhookEvent(hApplyIconHook); hApplyIconHook = NULL;
		UnhookEvent(hRebuildIconsHook); hRebuildIconsHook = NULL;
	}
	ApplyCListIcons();
}

/**
 * name:	OnModulesLoaded
 * desc:	initiate the module
 * params:	none
 * return:	0
 **/
VOID OnModulesLoaded()
{
	EnableExtraIcons(DBGetByte(SET_CLIST_EXTRAICON_PHONE, DEFVAL_CLIST_EXTRAICON_PHONE), FALSE);
}

} // namespace NServices
} // namespace NSendSMS
